MaxPoolFusion
对输入张量执行最大池化操作
\[\text{output}_{b, h_o, w_o, c} = \operatorname{clip}\Bigg( \max_{h_i, w_i \in \mathcal{W}(h_o, w_o)} \Big( \text{input}_{b,\; h_i,\; w_i,\; c} \Big),\; \text{minf},\; \text{maxf} \Bigg)\]其中,窗口区域 \(\mathcal{W}(h_o, w_o)\) 的定义如下:
\[ \begin{align}\begin{aligned}h_i = h_o \cdot \text{stride}_h - \text{pad}_u + \Delta h\\w_i = w_o \cdot \text{stride}_w - \text{pad}_l + \Delta w\\\Delta h \in [0,\ \text{win}_h - 1],\quad \Delta w \in [0,\ \text{win}_w - 1]\end{aligned}\end{align} \]有效窗口点满足:
\[0 \le h_i < \text{in}_h,\qquad 0 \le w_i < \text{in}_w\]原始窗口起点定义为:
\[h_{\text{start}} = h_o \cdot \text{stride}_h - \text{pad}_u\]\[w_{\text{start}} = w_o \cdot \text{stride}_w - \text{pad}_l\]合法采样范围为:
\[\Delta h \in \Big[ \max(0,\ -h_{\text{start}}),\; \min(\text{win}_h,\ \text{in}_h - h_{\text{start}}) \Big)\]\[\Delta w \in \Big[ \max(0,\ -w_{\text{start}}),\; \min(\text{win}_w,\ \text{in}_w - w_{\text{start}}) \Big)\]最大池化计算:
\[v_{\max} = \max_{\Delta h,\ \Delta w}\; \text{input}_{b,\; h_{\text{start}} + \Delta h,\; w_{\text{start}} + \Delta w,\; c}\]最终输出:
\[\text{output}_{b, h_o, w_o, c} = \min\big(\max(v_{\max},\ \text{minf}),\ \text{maxf}\big)\]
- 输入:
input - 输入张量指针,采用 NHWC 格式,形状为 \([batch,\ in\_h,\ in\_w,\ channel]\)
in_w - 输入张量的宽度 (W)
in_h - 输入张量的高度 (H)
win_w - 池化窗口的宽度,即窗口在 W 方向的大小
win_h - 池化窗口的高度,即窗口在 H 方向的大小
output_w - 输出特征图的宽度
output_h - 输出特征图的高度
batch - 批次大小,即输入中的 batch 数
channel - 通道数 C ,每个池化位置都分别对 C 个通道独立执行最大池化与裁剪
stride_w - 池化窗口在 W 方向的步长
stride_h - 池化窗口在 H 方向的步长
pad_l - 输入特征图左侧的填充大小
pad_u - 输入特征图上侧的填充大小
minf - 输出结果的下界值。池化结果会执行 \(\max(v,\ \text{minf})\)
maxf - 输出结果的上界值。池化结果会执行 \(\min(v,\ \text{maxf})\)
core_mask - 核心掩码,指定使用的计算核心
- 输出:
output - 输出张量指针,采用 NHWC 格式,形状为 \([batch,\ output\_h,\ output\_w,\ channel]\)。
- 支持平台:
FT78NEMT7004备注
FT78NE 支持fp32, fp64
MT7004 支持fp16, fp32
调用时将除 core_mask 外的参数打包通过 long long params 数组传入,顺序为: input, output, in_w, in_h, win_w, win_h, output_w, output_h, batch, channel, stride_w, stride_h, pad_l, pad_u, minf, maxf
共享存储版本:
-
void hp_maxpool_fusion_s(long long *params, int core_mask)
-
void fp_maxpool_fusion_s(long long *params, int core_mask)
-
void dp_maxpool_fusion_s(long long *params, int core_mask)
C调用示例:
1//FT78NE示例 2#include <stdio.h> 3 4int main(int argc, char* argv[]) { 5 float* input_ptr = (float*)0xA0000000; 6 float* output_ptr = (float*)0xB0000000; 7 float* check_ptr = (float*)0xC0000000; 8 int in_w = 32; 9 int in_h = 32; 10 int win_w = 6; 11 int win_h = 6; 12 int batch = 4; 13 int channel = 2; 14 int stride_w = 4; 15 int stride_h = 4; 16 int pad_l = 0; 17 int pad_u = 0; 18 float minf = 0.0f; 19 float maxf = 50.0f; 20 21 // 根据标准公式计算输出尺寸 22 int dividor = in_w + pad_l * 2 - win_w; 23 int output_w = (dividor + stride_w - 1) / stride_w + 1; 24 int dividor2 = in_h + pad_u * 2 - win_h; 25 int output_h = (dividor2 + stride_h - 1) / stride_h + 1; 26 27 long long params[16]; 28 params[0] = (long long)input_ptr; 29 params[1] = (long long)output_ptr; 30 params[2] = (long long)in_w; 31 params[3] = (long long)in_h; 32 params[4] = (long long)win_w; 33 params[5] = (long long)win_h; 34 params[6] = (long long)output_w; 35 params[7] = (long long)output_h; 36 params[8] = (long long)batch; 37 params[9] = (long long)channel; 38 params[10] = (long long)stride_w; 39 params[11] = (long long)stride_h; 40 params[12] = (long long)pad_l; 41 params[13] = (long long)pad_u; 42 params[14] = (long long)&minf; 43 params[15] = (long long)&maxf; 44 int core_mask = 0x0f; 45 fp_maxpool_fusion_s(params, core_mask); 46 return 0; 47}
私有存储版本:
-
void hp_maxpool_fusion_p(long long *params)
-
void fp_maxpool_fusion_p(long long *params)
-
void dp_maxpool_fusion_p(long long *params)
C调用示例:
1//FT78NE示例 2#include <stdio.h> 3 4int main(int argc, char* argv[]) { 5 float* input_ptr = (float*)0xA0000000; 6 float* output_ptr = (float*)0xB0000000; 7 float* check_ptr = (float*)0xC0000000; 8 int in_w = 32; 9 int in_h = 32; 10 int win_w = 6; 11 int win_h = 6; 12 int batch = 4; 13 int channel = 2; 14 int stride_w = 4; 15 int stride_h = 4; 16 int pad_l = 0; 17 int pad_u = 0; 18 float minf = 0.0f; 19 float maxf = 50.0f; 20 21 // 根据标准公式计算输出尺寸 22 int dividor = in_w + pad_l * 2 - win_w; 23 int output_w = (dividor + stride_w - 1) / stride_w + 1; 24 int dividor2 = in_h + pad_u * 2 - win_h; 25 int output_h = (dividor2 + stride_h - 1) / stride_h + 1; 26 27 long long params[16]; 28 params[0] = (long long)input_ptr; 29 params[1] = (long long)output_ptr; 30 params[2] = (long long)in_w; 31 params[3] = (long long)in_h; 32 params[4] = (long long)win_w; 33 params[5] = (long long)win_h; 34 params[6] = (long long)output_w; 35 params[7] = (long long)output_h; 36 params[8] = (long long)batch; 37 params[9] = (long long)channel; 38 params[10] = (long long)stride_w; 39 params[11] = (long long)stride_h; 40 params[12] = (long long)pad_l; 41 params[13] = (long long)pad_u; 42 params[14] = (long long)&minf; 43 params[15] = (long long)&maxf; 44 fp_maxpool_fusion_p(params); 45 return 0; 46}